package com.hoolai.qps.mina.proto;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import com.hoolai.qps.codes.mina.protobuf.ProtobufCodecFactory;
import com.hoolai.qps.proto.ReqCmdProto.SaveUserReqCmdProto;

public class ProxyServer {

    private static final Logger logger = Logger.getLogger(LogicServer.class);

    private static final ConcurrentHashMap<Long, IoSession> sessionGroup = new ConcurrentHashMap<Long, IoSession>();

    public static void main(String[] args) throws IOException {
        final IoSession session = initClient();
        logger.info("init client finish");
//        initServer(session);
//        logger.info("init server finish");
        logger.info("proxy server start!");
    }

    private static IoSession initClient() {
        NioSocketConnector connector = new NioSocketConnector();
        connector.setConnectTimeoutMillis(3000);
        connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(ProtobufCodecFactory.newInstance(SaveUserReqCmdProto.newBuilder().build())));
        connector.getFilterChain().addLast("logger", new LoggingFilter());
        connector.setHandler(new IoHandlerAdapter() {
            @Override
            public void messageReceived(IoSession session, Object message) throws Exception {
                logger.info("message received form logic:" + message);
                SaveUserReqCmdProto proto = (SaveUserReqCmdProto) message;
                if (null != proto) {
                    IoSession ioSession = null;//TODO $
                    if (null != ioSession) {
                        ioSession.write(proto);
                    }
                }
            }
        });

        ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1", 1111));
        future.awaitUninterruptibly();
        IoSession session = future.getSession();
        return session;
    }

    private static void initServer(final IoSession serverSession) throws IOException {
        IoAcceptor acceptor = new NioSocketAcceptor();

        acceptor.getFilterChain().addLast("logger", new LoggingFilter());
        acceptor.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(ProtobufCodecFactory.newInstance(SaveUserReqCmdProto.newBuilder().build())));

        acceptor.setHandler(new IoHandlerAdapter() {
            @Override
            public void messageReceived(IoSession session, Object message) throws Exception {
                SaveUserReqCmdProto proto = (SaveUserReqCmdProto) message;
                SaveUserReqCmdProto.Builder builder = SaveUserReqCmdProto.newBuilder();
                builder.setName(proto.getName());
                serverSession.write(builder.build());
            }

            @Override
            public void sessionOpened(IoSession session) throws Exception {
                sessionGroup.put(session.getId(), session);
            }
        });

        acceptor.getSessionConfig().setReadBufferSize(2048);
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
        acceptor.bind(new InetSocketAddress("127.0.0.1", 8888));
    }

}
